/** Container for correlation functions common to local and global trending 
 * 
 */
package trend;

import java.util.*;

/**
 * @author Hussein Patwa
 * @date 10 April 2008
 */
public class Correlation {

    double getCorrelationCoefficient(TreeMap obsPred){
        double sigmaX = sigmaX(obsPred.keySet());
        double sigmaX2 = sigmaXSquare(obsPred.keySet());
        double sigmaY = sigmaY(obsPred.values());
        double sigmaY2 = sigmaYSquare(obsPred.values());
        double sigmaXY = sigmaXY(obsPred);
        double numerator = (obsPred.size()*sigmaXY) - (sigmaX*sigmaY);
        double denominator = Math.sqrt(((obsPred.size()*sigmaX2)-Math.pow(sigmaX,2)))*Math.sqrt(((obsPred.size()*sigmaY2)-Math.pow(sigmaY,2)));
        return numerator/denominator;
    }    
    
    static public double sigmaX(Set dateSet){
        double rtn = 0;
        int j = 0;
        Double first = new Double(0);
        for(Iterator i = dateSet.iterator();i.hasNext();){
            Double key = (Double)i.next();
            if(j==0)
                first = key;
            rtn = rtn + (key.doubleValue()-first.doubleValue());
            j++;
        }
        return rtn;
    }

static public double sigmaXSquare(Set dateSet){
    double rtn = 0;
    int j = 0;
    Double first = new Double(0);
    for(Iterator i = dateSet.iterator();i.hasNext();){
        Double key = (Double)i.next();
        if(j==0)
            first = key;
        rtn = rtn + Math.pow((key.doubleValue()-first.doubleValue()),2);
        j++;
    }
    return rtn;
}



static public double sigmaY(Collection values){
    double rtn = 0;
    for(Iterator i = values.iterator();i.hasNext();){
        Double ctVal = (Double)i.next();
        rtn = rtn + ctVal.doubleValue();
    }
    return rtn;
}


static public double sigmaYSquare(Collection values){
    double rtn = 0;
    for(Iterator i = values.iterator();i.hasNext();){
        Double ctVal = (Double)i.next();
        rtn = rtn + Math.pow(ctVal.doubleValue(),2);
    }
    return rtn;
}

static public double sigmaXY(TreeMap series){
    double rtn = 0;
    Double first = (Double)series.firstKey();
    for(Iterator i = series.entrySet().iterator();i.hasNext();){
        Map.Entry e = (Map.Entry) i.next();
        Double key = (Double)e.getKey();
        Double ctVal = (Double)e.getValue();
        rtn = rtn + ((key.doubleValue()-first.doubleValue())*ctVal.doubleValue());
    }
    return rtn;
}

//Sample example of Wikipedia Correlation pseudo code from
//http://64.233.183.104/search?q=cache:f6bQ8-bRWQsJ:snippetsnap.com/snippets/4720-calculate-the-Pearson-s-correlation-in-JAVA+java+implementation+pearson+correlation&hl=en&ct=clnk&cd=3&gl=uk
public static double getPearsonCorrelation(double[] scores1,double[] scores2){        
	double result = 0;        
	double sum_sq_x = 0;        
	double sum_sq_y = 0;        
	double sum_coproduct = 0;        
	double mean_x = scores1[0];        
	double mean_y = scores2[0];        
	for(int i=2;i<scores1.length+1;i+=1){            
	    double sweep =Double.valueOf(i-1)/i;            
	    double delta_x = scores1[i-1]-mean_x;            
	    double delta_y = scores2[i-1]-mean_y;            
	    sum_sq_x += delta_x * delta_x * sweep;            
	    sum_sq_y += delta_y * delta_y * sweep;            
	    sum_coproduct += delta_x * delta_y * sweep;            
	    mean_x += delta_x / i;            
	    mean_y += delta_y / i;        }        
	double pop_sd_x = (double) Math.sqrt(sum_sq_x/scores1.length);        
	double pop_sd_y = (double) Math.sqrt(sum_sq_y/scores1.length);        
	double cov_x_y = sum_coproduct / scores1.length;        
	result = cov_x_y / (pop_sd_x*pop_sd_y);        
return result;    }


}
